package subgroup

import (
	"crypto/x509"
	"encoding/base64"
	"encoding/xml"
	"fmt"
	"math/rand"
	"time"

	"github.com/gofiber/fiber/v2"
)

// 主要处理函数
func handleMain(c *fiber.Ctx) error {
	return mainstart(c)
}

// RPC处理函数
func handleRPC(c *fiber.Ctx) error {
	return rpcHandler(c)
}

func mainstart(c *fiber.Ctx) error {
	// 公共数据：power配置信息，所有页面都需要
	key, _ := base64.StdEncoding.DecodeString(JetBraninsCertStr)
	mpk, _ := x509.ParseCertificate(key)
	powstr := CreatePower(mpk, RootPublicKey)
	key, _ = base64.StdEncoding.DecodeString(LicenseCertStr)
	lkey2, _ := x509.ParseCertificate(key)
	powstr2 := CreatePower(lkey2, LicenseRootPublicKey)
	
	// 创建数据映射
	data := fiber.Map{
		"powstr":  powstr,
		"powstr2": powstr2,
		"code":    "all",
		"pz":      "",
	}

	// 初始化生成注册码页面所需的字段
	Id := generateRandomId()
	Name := "johnroot"
	Md := "0120200728EPAJA801225"
	Hs := "127988766/0"
	Fd := "2999-05-20"
	Rs := "all"
	data["Name"] = Name
	data["Id"] = Id
	data["Fd"] = Fd
	data["Md"] = Md
	data["Hs"] = Hs
	data["sncode"] = ""

	// 根据不同URL设置页面特定数据
	switch c.Path() {
	case "/": // 首页
		data["currentPage"] = "home"
		return c.Render("home", data)

	case "/dumpkey": // 解析KEY页
		var crcret = ""
		var jcode = ""
		var pz = ""
		sj := c.FormValue("mkey")
		if len(sj) > 0 {
			crcret, jcode, pz = DumpKey(sj)
		}
		data["crcret"] = crcret
		data["gj"] = jcode
		data["pz"] = pz
		data["currentPage"] = "dumpkey"
		return c.Render("home", data)

	case "/getkey": // 生成key页
		sncode := ""
		if len(c.FormValue("keyid")) > 0 {
			Id = c.FormValue("keyid")
			Name = c.FormValue("username")
			Fd = c.FormValue("fallbackdate")
			Rs = c.FormValue("code")
			Md = c.FormValue("md")
			Hs = c.FormValue("hash")
			sncode = CreateKey(&Id, &Name, &Md, &Hs, &Fd, &Rs)
			Id = generateRandomId() // 生成新的ID供下次使用
		} else {
			sncode = ""
		}
		data["Name"] = Name
		data["Id"] = Id
		data["Fd"] = Fd
		data["Md"] = Md
		data["Hs"] = Hs
		data["sncode"] = sncode
		data["code"] = Rs
		data["currentPage"] = "getcode"
		return c.Render("home", data)

	default:
		return c.SendStatus(401)
	}
}

// RPC处理函数
func rpcHandler(c *fiber.Ctx) error {
	switch c.Path() {
	case "/rpc/ping.action", "/rpc/releaseTicket.action", "/rpc/prolongTicket.action":
		xj := xmlData{}
		var machineId string
		machineId = c.FormValue("machineId")
		leaseContent := "4567888888888:" + getserverUid() //服务器到期时间  + serverUid
		xj.Action = "NONE"
		xj.ConfirmationStamp = getConfirmationStamp(machineId)
		xj.LeaseSignature = getLeaseSignature(leaseContent)
		xj.Message = ""
		xj.ResponseCode = "OK"
		xj.Salt = c.FormValue("salt")
		xj.ServerLease = leaseContent
		xj.ServerUid = getserverUid()
		xj.ValidationDeadlinePeriod = "-1"
		xj.ValidationPeriod = "600000"
		var xm interface{}
		switch c.Path() {
		case "/rpc/ping.action":
			xm = PingResponse{xmlData: xj}
		case "/rpc/releaseTicket.action":
			xm = ReleaseTicketResponse{xmlData: xj}
		case "/rpc/prolongTicket.action":
			xm = ProlongTicketResponse{xmlData: xj}
		}
		xData, _ := xml.Marshal(&xm)
		retStr := getSignXml(string(xData))
		c.Set("Content-Type", "application/xml;charset=utf-8")
		return c.SendString(retStr)
		
	case "/rpc/obtainTicket.action":
		machineId := c.FormValue("machineId")
		leaseContent := "4567888888888:" + getserverUid() //服务器到期时间  + serverUid
		ticketProperties := fmt.Sprintf("<ticketProperties>licensee=%s\tlicenseeType=5\tmetaData=0120211980PSAN801225</ticketProperties>", c.FormValue("userName"))
		xj := ObtainTicketResponse{}
		xj.Action = "NONE"
		xj.ConfirmationStamp = getConfirmationStamp(machineId)
		xj.LeaseSignature = getLeaseSignature(leaseContent)
		xj.Message = ""
		xj.ProlongationPeriod = "600000"
		xj.ResponseCode = "OK"
		xj.Salt = c.FormValue("salt")
		xj.ServerLease = leaseContent
		xj.ServerUid = getserverUid()
		xj.TicketId = getTicketId()
		xj.TicketProperties = ticketProperties
		xj.ValidationDeadlinePeriod = "-1"
		xj.ValidationPeriod = "600000"
		xmldata, _ := xml.Marshal(&xj)
		retstr := getSignXml(string(xmldata))
		c.Set("Content-Type", "application/xml;charset=utf-8")
		return c.SendString(retstr)
		
	default:
		return c.SendStatus(401)
	}
	return nil
}

// 生成随机ID的辅助函数
func generateRandomId() string {
	sz := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	tid := make([]byte, 10)
	rs := rand.NewSource(time.Now().UnixNano())
	for i := 0; i < 10; i++ {
		p := rand.New(rs).Intn(len(sz))
		tid[i] = []byte(sz)[p]
	}
	return string(tid)
}
